/**
 * @file
 * @author
 * @date
 * @brief
 */
#include "Motor.h"
#include "app_trace.h"
#include "app_util_platform.h"
#include "board_cfg.h"
#include "display_ctrl.h"
#include "display_drv.h"
#include "lcd_extra.h"
#include "nrf_delay.h"
#include "nrf_drv_common.h"
#include "nrf_gpio.h"
#include "nrf_spi.h"
#include "nrf_spim.h"
#define LOG(fmt, ...) app_trace_log(fmt "\r\n", ##__VA_ARGS__)

void oled_write_data_16(uint16_t value)
{
    oled_write_data(((value) >> 8) & 0xFF);
    oled_write_data((value)&0xFF);
}
void oled_write_cmd_16(uint16_t value)
{
    oled_write_cmd(((value) >> 8) & 0xFF);
    oled_write_cmd((value)&0xFF);
}
/*********************************************************************************************
 * @brief
 * @param [in] param1
 * @param [out] param2
 * @return ret
 * @note
 * @warning
 ********************************************************************************************/
void lcd_set_xy_without_data(uint16_t Xstart, uint16_t Xend, uint16_t Ystart, uint16_t Yend)
{
    // LOG("{%d, %d} {%d,%d}", Xstart, Xend, Ystart, Yend);
    oled_write_cmd_16(0x36);
    oled_write_data_16(Xend + OLED_OFFSET_X);
    oled_write_cmd_16(0x37);
    oled_write_data_16(Xstart + OLED_OFFSET_X);
    oled_write_cmd_16(0x38);
    oled_write_data_16(Yend);
    oled_write_cmd_16(0x39);
    oled_write_data_16(Ystart);
    // LOG("0x%02X, 0x%02X, 0x%02X, 0x%02X", Xend + OLED_OFFSET_X, Xstart + OLED_OFFSET_X, Yend, Ystart);
}

void lcd_set_xy(uint16_t Xstart, uint16_t Xend, uint16_t Ystart, uint16_t Yend)
{
    lcd_set_xy_without_data(Xstart, Xend, Ystart, Yend);
    oled_write_cmd_16(0x22);
}

/*********************************************************************************************
 * @brief 填入数据
* @warning 图片w/h大小都不能超过255
                    注意！！p_data会自动根据OLED_SIZE_X跳跃
 ********************************************************************************************/
void oled_fill_data(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *p_data)
{
    lcd_set_xy(x, x + w - 1, y, y + h - 1);
    if (get_spi_mode() != SPI_CFG_MODE_SOFTWARE)
    {
        spi_switch_mode(SPI_CFG_MODE_HARDWARE_DMA);
    }
    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);

    uint16_t *color = (uint16_t *)p_data;
    uint16_t cnt = w * h;
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                oled_spi_tx_byte(p_data[j + 1]);
                oled_spi_tx_byte(p_data[j]);
            }
            p_data += w * 2; // 2字节
        }
    }
    else if (get_spi_mode() == SPI_CFG_MODE_HARDWARE_DMA)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                *color = __REV16(*color);
                color++;
            }
        }
        spim_tx(p_data, w, h * 2 - 1);
        // spim_wait_finish();
    }
    else
    {
        oled_spi_tx_bytes_hw(p_data, cnt * 2);
        oled_spi_hw_wait_end();
        nrf_gpio_pin_set(OLED_CS_PIN);
    }
}

/*********************************************************************************************
 * @brief 填入数据
* @warning 图片w/h大小都不能超过255
                    注意！！p_data会自动根据OLED_SIZE_X跳跃
 ********************************************************************************************/
void oled_fill_data_continue(uint16_t w, uint16_t h, const uint8_t *p_data)
{
    if (get_spi_mode() != SPI_CFG_MODE_SOFTWARE)
    {
        spi_switch_mode(SPI_CFG_MODE_HARDWARE_DMA);
    }
    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);

    uint16_t cnt = w * h;
    uint16_t *color = (uint16_t *)p_data;
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                oled_spi_tx_byte(p_data[j + 1]);
                oled_spi_tx_byte(p_data[j]);
            }
            p_data += w * 2; // 2字节
        }
    }
    else if (get_spi_mode() == SPI_CFG_MODE_HARDWARE_DMA)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                *color = __REV16(*color);
                color++;
            }
        }
        spim_tx(p_data, w, h * 2 - 1);
        // spi_switch_mode(SPI_CFG_MODE_HARDWARE);
    }
    else
    {
        oled_spi_tx_bytes_hw(p_data, cnt * 2);
        oled_spi_hw_wait_end();
        nrf_gpio_pin_set(OLED_CS_PIN);
    }
}
/*********************************************************************************************
 * @brief 全屏填入颜色
 * @warning
 ********************************************************************************************/
void oled_all_fill_data(uint16_t data)
{
    lcd_set_xy(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);

    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);
    uint8_t buffer[2] = {data >> 8, data & 0xff};
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        for (uint16_t i = 0; i < OLED_SIZE_X * OLED_SIZE_Y; i++)
        {
            oled_spi_tx_byte(buffer[0]);
            oled_spi_tx_byte(buffer[1]);
        }
    }
    else
    {
        for (uint16_t i = 0; i < OLED_SIZE_X * OLED_SIZE_Y; i++)
        {
            oled_spi_tx_bytes_hw(buffer, 2);
        }
    }

    oled_spi_hw_wait_end();
    nrf_gpio_pin_set(OLED_CS_PIN);
}

/*********************************************************************************************
 * @brief 清屏并恢复RAM映射
 * @warning
 ********************************************************************************************/
void oled_reset_clear(void)
{
    lcd_set_ram_offset(0);
    lcd_set_xy(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);

    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);
    uint8_t buffer[2] = {0 >> 8, 0 & 0xff};
    for (uint32_t i = 0; i < OLED_SIZE_X * OLED_RAM_Y_MAX; i++)
    {
        oled_spi_tx_bytes_hw(buffer, 2);
    }
    oled_spi_hw_wait_end();
    nrf_gpio_pin_set(OLED_CS_PIN);
}

// #define LCD_RAM_DEFAULT_OFFSET 280

/*********************************************************************************************
 * @brief 设置RAM的偏移量
 * @param [in] param1
 * @param [out] param2
 * @return ret
 * @note
 * @warning RAM范围0~319，
 ********************************************************************************************/
void lcd_set_ram_offset(uint16_t offset)
{
    LOG("offset %d", offset);
    offset = (offset + LCD_RAM_DEFAULT_OFFSET) % OLED_RAM_Y_MAX;
#ifdef SCREEN_XY_MIRROR
    offset = OLED_RAM_Y_MAX - offset;
#endif
    // LOG("%d", offset);
    // oled_write_cmd(0x37);
    // oled_write_data(offset >> 8);
    // oled_write_data(offset & 0xFF);
}

void lcd_drv_set_param(void)
{
    lcd_extra_config();

    oled_write_cmd_16(0x00ff);
    oled_write_data_16(0x5aa5);

    oled_write_cmd_16(0x00f6);
    oled_write_data_16(0x0112);

    oled_write_cmd_16(0x00ef);
    oled_write_data_16(0x1052);

    oled_write_cmd_16(0x00a5);
    oled_write_data_16(0x0780);

    oled_write_cmd_16(0x0002);
    oled_write_data_16(0x0100);

    oled_write_cmd_16(0x0003);
    oled_write_data_16(0x1030);

    oled_write_cmd_16(0x0001);
    oled_write_data_16(0x011c);

    oled_write_cmd_16(0x0010);
    oled_write_data_16(0x0000);

    oled_write_cmd_16(0x0011);
    oled_write_data_16(0x1000);

    oled_write_cmd_16(0x0020);
    oled_write_data_16(0x0000);

    oled_write_cmd_16(0x0021);
    oled_write_data_16(0x0000);

    oled_write_cmd_16(0x0030);
    oled_write_data_16(0x0000);

    oled_write_cmd_16(0x0031);
    oled_write_data_16(0x00DB);

    oled_write_cmd_16(0x0032);
    oled_write_data_16(0x0000);

    oled_write_cmd_16(0x0033);
    oled_write_data_16(0x0000);

    oled_write_cmd_16(0x0034);
    oled_write_data_16(0x00DB);

    oled_write_cmd_16(0x0035);
    oled_write_data_16(0x0000);

    // oled_write_cmd_16(0x0036);
    // oled_write_data_16(0x0097);

    // oled_write_cmd_16(0x0037);
    // oled_write_data_16(0x0018);

    // oled_write_cmd_16(0x0038);
    // oled_write_data_16(0x00DB);

    // oled_write_cmd_16(0x0039);
    // oled_write_data_16(0x0000);

    oled_write_cmd_16(0x0050);
    oled_write_data_16(0xf980);

    oled_write_cmd_16(0x0051);
    oled_write_data_16(0x2218);

    oled_write_cmd_16(0x0052);
    oled_write_data_16(0x0609);

    oled_write_cmd_16(0x0053);
    oled_write_data_16(0x3b04);

    oled_write_cmd_16(0x0054);
    oled_write_data_16(0x4c1b);

    oled_write_cmd_16(0x0055);
    oled_write_data_16(0x1b10);

    oled_write_cmd_16(0x0056);
    oled_write_data_16(0x3f2e);

    oled_write_cmd_16(0x0057);
    oled_write_data_16(0xf580);

    oled_write_cmd_16(0x0058);
    oled_write_data_16(0x2218);

    oled_write_cmd_16(0x0059);
    oled_write_data_16(0x0613);

    oled_write_cmd_16(0x005A);
    oled_write_data_16(0x4704);

    oled_write_cmd_16(0x005B);
    oled_write_data_16(0x601b);

    oled_write_cmd_16(0x005C);
    oled_write_data_16(0x0f01);

    oled_write_cmd_16(0x005D);
    oled_write_data_16(0x3f2e);

    oled_write_cmd_16(0x000f);
    oled_write_data_16(0x0901);

    oled_write_cmd_16(0x00eb);
    oled_write_data_16(0x041f);

    oled_write_cmd_16(0x00ec);
    oled_write_data_16(0x0a3c);

    oled_write_cmd_16(0x00E8);
    oled_write_data_16(0x0000);

    oled_write_cmd_16(0x00Ed);
    oled_write_data_16(0x3008);

    oled_write_cmd_16(0x0007);
    oled_write_data_16(0x1013);

    oled_write_cmd_16(0x00fe);
}
/*********************************************************************************************
 * @brief 显示驱动初始化
 * @param [in] param1
 * @param [out] param2
 * @return ret
 * @note
 * @warning
 ********************************************************************************************/
void lcd_drv_init(void)
{
    oled_spi_init(SPI_CFG_MODE_HARDWARE_DMA);
    nrf_gpio_cfg_output(OLED_DC_PIN);
#if USE_OLED_RESET

    nrf_gpio_pin_write(OLED_RESET_PIN, 1);
    nrf_delay_us(200);

    nrf_gpio_pin_write(OLED_RESET_PIN, 0);
    nrf_delay_us(800);

    nrf_gpio_pin_write(OLED_RESET_PIN, 1);
    nrf_delay_us(800);
#else
    // oled_write_cmd(0x01);
    // nrf_delay_ms(120);
#endif

    lcd_drv_set_param();
}
/*********************************************************************************************
 * @brief 关闭显示
 * @warning
 ********************************************************************************************/
void oled_turn_off(void)
{
#warning TODO:
    // LOG("oled_turn_off");
    // oled_write_cmd(0x28);
    // nrf_delay_ms(1);
    // oled_write_cmd(0x10); // sleep in
    // nrf_delay_ms(120);
}
/*********************************************************************************************
 * @brief 打开显示
 * @warning
 ********************************************************************************************/

void oled_turn_on(void)
{
#warning TODO:
    // #if defined(R911_V1_1_BOARD)
    //     peripheral_oledpower_On();
    // #endif
    // #if 0 // defined(R911_V1_11_BOARD)
    //     peripheral_oledpower_On();
    //     nrf_delay_ms(120);
    //     oled_write_cmd(0x28);
    // #endif
    //     // nrf_delay_ms(500);
    //     lcd_drv_set_param();
    // #if 0 // defined(R911_V1_11_BOARD)
    // #else
    //     oled_write_cmd(0x29);
    //     oled_write_cmd(0x11); // sleep out
    //     nrf_delay_ms(5);
    // #endif
}
#if 0 // defined(R911_V1_11_BOARD)
void oled_display_on(void)
{
    oled_write_cmd(0x29);
    oled_write_cmd(0x11); // sleep out
    nrf_delay_ms(5);
}
#endif
